﻿Imports DotSpatial.Controls
Imports DotSpatial.Symbology
Imports System.Threading.Tasks

Public Class frmD4EM

    Private IsCancelled As Boolean = False
    Private IsDownloading As Boolean = False

    Private Sub btnDownload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDownload.Click
        tblMap.Visible = False
        DownloadLayers()
        Me.Close()
    End Sub

    Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
        IsCancelled = True
        lblStatus.Visible = True
        If Not IsDownloading Then Me.Close()
    End Sub

    Private Sub cboCategory_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles cboCategory.SelectedIndexChanged
        With lstDataTypes.Items
            .Clear()
            .Add("All")
            Select Case cboCategory.SelectedIndex
                Case 0 'Basins
                    'DEM shapefile and PCS don't extract correctly (and are already included in the Core data)
                    '.AddRange(New String() {"BASINS Core", "Census Data", "DEM Shapefile", "DEM Grid", "GIRAS Land Use", "12-Digit Cataloging Unit Boundaries", "Legacy STORET Stations", "National Elevation Dataset", "National Hydrologic Dataset", "Permit Compliance System"})
                    .AddRange(New String() {"BASINS Core", "Census Data", "DEM Grid", "GIRAS Land Use", "12-Digit Cataloging Unit Boundaries", "Legacy STORET Stations", "National Elevation Dataset", "National Hydrologic Dataset"})
                Case 1 'USGS
                    .AddRange(New String() {"1992 LandCover", "2001 LandCover", "2001 Canopy", "2001 Impervious", "2006 LandCover", "2006 Impervious", "NED 1 ArcSecond", "NED 1/3 ArcSecond"})
                Case 2 'NHDPlus
                    .AddRange(New String() {"Catchment Grid", "Catchment Polygons", "Elevation Grid", "Flow Accumulation Grid", "Flow Direction Grid", "Slope Grid", "Hydrography Area", "Hydrography Flowline", "Hydrography Line", "Hydrography Point", "Hydrography Waterbody", "Hydrologic Units-Region Polygons", "Hydrologic Units-Sub Basin Polygons", "Hydrologic Units-Sub Watershed Polygons", "Hydrologic Units-Watershed Polygons"})
            End Select
        End With
    End Sub

    Private Sub lstDataTypes_ItemCheck(sender As Object, e As System.Windows.Forms.ItemCheckEventArgs) Handles lstDataTypes.ItemCheck

        Static SuspendUpdates As Boolean = False

        Try

            If SuspendUpdates Then Exit Sub
            SuspendUpdates = True

            With lstDataTypes
                If e.Index = 0 Then 'All item; set all others to match
                    For i As Integer = 1 To .Items.Count - 1
                        .SetItemChecked(i, e.NewValue)
                    Next
                Else 'one of the sub items; figure out how many are checked and then reset state of All item
                    Dim AllChecked As Boolean = True
                    Dim SomeChecked As Boolean = False
                    For i As Integer = 1 To .Items.Count - 1
                        If i = e.Index Then
                            If e.NewValue = CheckState.Unchecked Then AllChecked = False
                        ElseIf Not .GetItemChecked(i) Then
                            AllChecked = False
                        End If
                    Next
                    For i As Integer = 1 To .Items.Count - 1
                        If i = e.Index Then
                            If e.NewValue = CheckState.Checked Then SomeChecked = True
                        ElseIf .GetItemChecked(i) Then
                            SomeChecked = True
                        End If
                    Next
                    .SetItemCheckState(0, IIf(AllChecked, CheckState.Checked, IIf(SomeChecked, CheckState.Indeterminate, CheckState.Unchecked)))
                End If
            End With

            Application.DoEvents()

            UpdateBtnDownload()

        Catch ex As Exception

            ErrorMsg(, ex)

        Finally

            SuspendUpdates = False

        End Try

    End Sub

    Private Sub frmD4EM_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        If IsDownloading Then
            If WarningMsg("Do you want to abort the downloading operation?") = Windows.Forms.DialogResult.OK Then IsCancelled = True
            e.Cancel = True
        End If
    End Sub

    Private Sub frmD4EM_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
        If e.KeyCode = Keys.Escape Then HucMap.FunctionMode = FunctionMode.Select
    End Sub

    Private Sub frmD4EM_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        lblFiles.Text = GISForm.LayerDirectory
        lblCache.Text = GISForm.CacheDirectory
        cboHUC.Text = GetSetting(REGAPP, Name, "cboHUC", "HUC8")
        txtHUC.Text = GetSetting(REGAPP, Name, "HUC")
        lblHUCName.Text = GetSetting(REGAPP, Name, "HUCName")
        cboCategory.SelectedIndex = 0
        btnDownload.Enabled = False
    End Sub

    Private Sub frmD4EM_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        RemoveHandler HucMap.SelectionChanged, AddressOf MapSelectionChanged
    End Sub

    Private Sub btnSelect_Click(sender As System.Object, e As System.EventArgs) Handles btnSelect.Click
        Me.Cursor = Cursors.WaitCursor

        'add national layers from bottom to top
        LoadIfNotFound("cnty", "Political", "Counties", Color.Gray, 1, True, False, False, True, 20)
        LoadIfNotFound("st", "Political", "States", Color.Red, 3, True, False, False)
        Dim lyr As FeatureLayer = LoadIfNotFound(Choose(cboHUC.SelectedIndex + 1, "huc250d3", "huc12"), "Hydrology", "HUC Basins", Color.Blue, 2, True, True, True, True, 10)
        If lyr Is Nothing Then Exit Sub
        HucMap.ViewExtents = lyr.Extent
        tblMap.Visible = True
        HucMap.Select()
        frmInfoMsg.ShowInfoMsg("Select HUC Watershed", "To select the desired HUC watershed, zoom/pan to your geographic area of interest and then select the watershed by clicking on it.\n\nNote: you are initially set to 'Pan/Zoom' mode where you left click and drag to pan, and roll the mouse wheel to zoom. To select a particular HUC, you must change to 'Select' mode by clicking on the top toolbar button. You can also toggle between Select and Pan/Zoom modes by double-clicking on the map.")
        HucMap.FunctionMode = FunctionMode.Pan
        AddHandler HucMap.SelectionChanged, AddressOf MapSelectionChanged
        Me.Cursor = Cursors.Default
    End Sub

    ''' <summary>
    ''' Load shapefile from National layers supplied with application if not already found
    ''' </summary>
    ''' <param name="ShapeFileName">Name of shapefile (no path or extension)</param>
    ''' <returns>Layer found or loaded</returns>
    Private Function LoadIfNotFound(ShapeFileName As String, GroupName As String, LayerName As String,
                                    OutlineColor As Color, OutlineWidth As Integer, Visible As Boolean, CanSelect As Boolean, IsSelected As Boolean,
                                    Optional UseDynamic As Boolean = False, Optional DynamicWidth As Double = 0.0) As FeatureLayer

        Try

            With HucMap

                'look for specified layer regardless of group
                For Each grp As MapGroup In .GetAllGroups
                    For Each lyr As IMapLayer In grp.GetLayers
                        If TypeOf lyr Is FeatureLayer Then
                            If String.Equals(IO.Path.GetFileNameWithoutExtension(CType(lyr, FeatureLayer).DataSet.Filename), ShapeFileName, StringComparison.OrdinalIgnoreCase) Then
                                lyr.IsVisible = True
                                Return lyr
                            End If
                        End If
                    Next
                Next

                'add if not found
                Dim Group As MapGroup = Nothing

                For Each grp As MapGroup In .GetAllGroups
                    If String.Equals(grp.LegendText, GroupName, StringComparison.OrdinalIgnoreCase) Then Group = grp : Exit For
                Next

                If Group Is Nothing Then Group = New MapGroup(HucMap, GroupName)

                'if layer wasn't found, add to group

                Dim filename As String = String.Format("{0}\data\National\{1}.shp", My.Application.Info.DirectoryPath, ShapeFileName)
                If Not My.Computer.FileSystem.FileExists(filename) Then
                    WarningMsg("Unable to find the required reference shape file: {0}.", filename.Replace("\", "\\"))
                    Return Nothing
                End If

                Dim lyrAdded As FeatureLayer = Group.Layers.Add(String.Format("data\National\{0}.shp", ShapeFileName))
                With lyrAdded
                    .LegendText = LayerName
                    .Reproject(ProjectProjection)
                    Dim sp As New SimplePattern(OutlineColor)
                    sp.Opacity = 0.5
                    Dim sym = New PolygonSymbolizer(Color.Transparent, OutlineColor, OutlineWidth)
                    .Symbolizer = sym
                    .IsVisible = Visible
                    .SelectionEnabled = CanSelect
                    .IsSelected = IsSelected
                    .DynamicVisibilityMode = DynamicVisibilityMode.ZoomedIn
                    .UseDynamicVisibility = UseDynamic
                    .DynamicVisibilityWidth = DynamicWidth
                End With

                Return lyrAdded

            End With

        Catch ex As Exception

            ErrorMsg(, ex)
            Return Nothing

        End Try

    End Function

    Private Sub MapSelectionChanged(sender As Object, e As EventArgs)
        With HucMap
            txtHUC.Text = ""
            lblHUCName.Text = ""
            If TypeOf .Layers.SelectedLayer Is MapPolygonLayer Then
                Dim polylayer As MapPolygonLayer = .Layers.SelectedLayer
                If polylayer.DataSet.DataTable.Columns.Contains("CU") AndAlso
                    (polylayer.DataSet.DataTable.Columns.Contains("CATNAME") OrElse
                     polylayer.DataSet.DataTable.Columns.Contains("HU_12_Name")) Then 'is HUC layer
                    If polylayer.Selection.Count = 1 Then
                        txtHUC.Text = polylayer.Selection.ToFeatureList(0).DataRow("CU")
                        lblHUCName.Text = polylayer.Selection.ToFeatureList(0).DataRow("CATNAME")
                    End If
                End If
            End If
        End With
    End Sub

    Private Function LoadDLL(FileName As String) As Reflection.Assembly
        Dim f As String = IO.Path.Combine(My.Application.Info.DirectoryPath, "Plugins\GDAL\", FileName, ".dll")
        If My.Computer.FileSystem.FileExists(f) Then
            Return Reflection.Assembly.LoadFrom(f)
        Else
            Throw New IO.FileLoadException("Unable to find required library; please reinstall the application.", f)
            Return Nothing
        End If
    End Function

    Private Sub DownloadLayers()

        Try

            Dim HUC As String = Me.txtHUC.Text.Trim
            Dim length As Integer = Choose(cboHUC.SelectedIndex + 1, 8, 12)
            If Not (HUC.Length = length And IsNumeric(HUC)) Then
                WarningMsg("The HUC must be a valid 8- or 12-digit hydrologic unit code.")
                Exit Sub
            End If

            SaveSetting(REGAPP, Me.Name, "cboHUC", cboHUC.Text)
            SaveSetting(REGAPP, Me.Name, "HUC", HUC)
            SaveSetting(REGAPP, Name, "HUCName", lblHUCName.Text)

            Dim lyrSpec As D4EM.Data.LayerSpecification = Choose(cboHUC.SelectedIndex + 1, D4EM.Data.Region.RegionTypes.huc8, D4EM.Data.Region.RegionTypes.huc12)
            Dim Region As New D4EM.Data.Region(lyrSpec, HUC)
            Dim Project As New D4EM.Data.Project(ProjectProjection, GISForm.CacheDirectory, GISForm.LayerDirectory, Region, False, False)

            GISForm.GISMap.Layers.SuspendEvents()

            IsCancelled = False
            IsDownloading = True

            btnDownload.Enabled = False
            btnClose.Text = "Cancel"

            Dim sw As New Stopwatch
            sw.Start()

            'If True Then 'use parallel processing

            Dim DownloadType As Integer = cboCategory.SelectedIndex
            Dim dictLayerFiles As New Generic.Dictionary(Of String, String)

            Dim lstWarningMsg As New Generic.List(Of String)

            Dim lstDownloadTypes As New Generic.List(Of String)
            For Each item In lstDataTypes.CheckedItems
                If item.ToString <> "All" Then lstDownloadTypes.Add(item.ToString)
            Next

            Dim numComplete As Integer = 0
            Dim numLayers As Integer = lstDownloadTypes.Count

            'start a background task to free up the UI, and then download in parallel

            GISForm.WriteProgress("Downloading {0} layers; please stand by...", lstDownloadTypes.Count)

            Dim t As New Task(
                Sub()
                    Dim ParOpt As New ParallelOptions
                    If DownloadType <> 1 Then ParOpt.MaxDegreeOfParallelism = 1 'basins shapefile download give errors if run in parallel
                    Parallel.ForEach(lstDownloadTypes, ParOpt,
                                     Sub(GroupName)

                                         If IsCancelled Then Exit Sub
                                         Dim DataType As D4EM.Data.LayerSpecification = Nothing
                                         Select Case GroupName
                                             Case "BASINS Core" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.core31.all
                                             Case "Census Data" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.Census.all
                                             Case "DEM Shapefile" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.dem
                                             Case "DEM Grid" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.DEMG
                                             Case "GIRAS Land Use" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.giras
                                             Case "12-Digit Cataloging Unit Boundaries" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.huc12
                                             Case "Legacy STORET Stations" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.lstoret
                                             Case "National Elevation Dataset" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.NED
                                             Case "National Hydrologic Dataset" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.nhd
                                             Case "Permit Compliance System" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.pcs3
                                             Case "1992 LandCover" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NLCD1992.LandCover
                                             Case "2001 LandCover" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NLCD2001.LandCover
                                             Case "2001 Canopy" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NLCD2001.Canopy
                                             Case "2001 Impervious" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NLCD2001.Impervious
                                             Case "2006 LandCover" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NLCD2006.LandCover
                                             Case "2006 Impervious" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NLCD2006.Impervious
                                             Case "NED 1 ArcSecond" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NED.OneArcSecond
                                             Case "NED 1/3 ArcSecond" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NED.OneThirdArcSecond
                                             Case "Catchment Grid" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.CatchmentGrid
                                             Case "Catchment Polygons" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.CatchmentPolygons
                                             Case "Elevation Grid" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.ElevationGrid
                                             Case "Flow Accumulation Grid" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.FlowAccumulationGrid
                                             Case "Flow Direction Grid" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.FlowDirectionGrid
                                             Case "Slope Grid" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.SlopeGrid
                                             Case "Hydrography Area" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.Hydrography.Area
                                             Case "Hydrography Flowline" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.Hydrography.Flowline
                                             Case "Hydrography Line" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.Hydrography.Line
                                             Case "Hydrography Point" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.Hydrography.Point
                                             Case "Hydrography Waterbody" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.Hydrography.Waterbody
                                             Case "Hydrologic Units-Region Polygons" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.HydrologicUnits.RegionPolygons
                                             Case "Hydrologic Units-Sub Basin Polygons" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.HydrologicUnits.SubBasinPolygons
                                             Case "Hydrologic Units-Sub Watershed Polygons" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.HydrologicUnits.SubWatershedPolygons
                                             Case "Hydrologic Units-Watershed Polygons" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.HydrologicUnits.WatershedPolygons
                                             Case Else
                                                 Throw New IndexOutOfRangeException("Invalid DataType encountered.")
                                         End Select

                                         Dim SaveFolder As String = DataType.Tag & "_" & HUC
                                         Dim DataDir As String = IO.Path.Combine(GISForm.LayerDirectory, SaveFolder)
                                         Dim DownloadResults As String = ""

                                         numComplete += 1
                                         GISForm.WriteProgress(numComplete - 1, numLayers, "Downloading {0} of {1} layers; please stand by...", numComplete, numLayers)
                                         Application.DoEvents()
                                         Debug.Print("=========>>>Downloaded {0} of {1} layers; please stand by...", numComplete, numLayers)

                                         Try
                                             Select Case DownloadType
                                                 Case 0
                                                     DownloadResults = D4EM.Data.Source.BASINS.GetBASINS(Project, SaveFolder, HUC, DataType)
                                                 Case 1
                                                     DownloadResults = D4EM.Data.Source.USGS_Seamless.Execute(Project, SaveFolder, DataType)
                                                 Case 2
                                                     DownloadResults = D4EM.Data.Source.NHDPlus.GetNHDPlus(Project, SaveFolder, HUC, True, New D4EM.Data.LayerSpecification() {DataType})
                                             End Select

                                             Debug.Print("Download: {0}; message: {1}", SaveFolder, DownloadResults)

                                             If My.Computer.FileSystem.DirectoryExists(DataDir) Then
                                                 For Each s As String In My.Computer.FileSystem.GetFiles(DataDir, FileIO.SearchOption.SearchAllSubDirectories, New String() {"*.shp", "*.tif"})
                                                     dictLayerFiles.Add(s, GroupName)
                                                 Next
                                             Else
                                                 lstWarningMsg.Add(String.Format("{0} in {1}; No downloaded data could be found.", GroupName, DataDir))
                                             End If

                                         Catch ex As Exception
                                             lstWarningMsg.Add(String.Format("{0} in {1}; Unable to download and/or extract information; the projection string on the downloaded layer may be invalid; you can try to manually open the file and correct this condition.", GroupName, DataDir))
                                         End Try
                                     End Sub)
                End Sub)

            t.Start()

            While t.Status <> TaskStatus.RanToCompletion
                Threading.Thread.Sleep(100)
                If IsCancelled Then Exit Sub
                Application.DoEvents()
            End While

            'GetBasins contains XML with layers acquired, but will just load layers by looking for shape files

            'use XML file from BASINS to assign layer name, group, and initial visibility

            For Each kv In dictLayerFiles
                GISForm.WriteProgress("Loading layer: {0}...", IO.Path.GetFileName(kv.Key))
                Dim lyr As IMapLayer = GISForm.GISMap.Layers.Add(kv.Key)
                GISForm.ApplyRendering(lyr, kv.Key, kv.Value)
            Next

            If dictLayerFiles.Count = 0 Then
                WarningMsg("No layer files were downloaded.")
            ElseIf lstWarningMsg.Count > 0 Then
                Dim s As String = ""
                For Each ss As String In lstWarningMsg
                    s &= ss & "\n\n"
                Next
                WarningMsg(StringFormat("The following warnings were issued:\n\n" & s))
            End If

            'Else
            '    For i As Integer = 1 To lstDataTypes.Items.Count - 1

            '        Application.DoEvents()
            '        If IsCancelled Then Exit For

            '        If lstDataTypes.GetItemChecked(i) Then

            '            GISForm.WriteProgress("Downloading {0}...", lstDataTypes.Items(i).ToString)

            '            Dim mwProgress As New MapWinProgress 'this will capture download progress
            '            MapWinUtility.Logger.ProgressStatus = mwProgress

            '            Dim DataType As D4EM.Data.LayerSpecification = Nothing
            '            Select Case lstDataTypes.Items(i).ToString
            '                Case "BASINS Core" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.core31.all
            '                Case "Census Data" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.Census.all
            '                Case "DEM Shapefile" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.dem
            '                Case "DEM Grid" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.DEMG
            '                Case "GIRAS Land Use" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.giras
            '                Case "12-Digit Cataloging Unit Boundaries" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.huc12
            '                Case "Legacy STORET Stations" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.lstoret
            '                Case "National Elevation Dataset" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.NED
            '                Case "National Hydrologic Dataset" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.nhd
            '                Case "Permit Compliance System" : DataType = D4EM.Data.Source.BASINS.LayerSpecifications.pcs3
            '                Case "1992 LandCover" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NLCD1992.LandCover
            '                Case "2001 LandCover" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NLCD2001.LandCover
            '                Case "2001 Canopy" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NLCD2001.Canopy
            '                Case "2001 Impervious" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NLCD2001.Impervious
            '                Case "2006 LandCover" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NLCD2006.LandCover
            '                Case "2006 Impervious" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NLCD2006.Impervious
            '                Case "NED 1 ArcSecond" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NED.OneArcSecond
            '                Case "NED 1/3 ArcSecond" : DataType = D4EM.Data.Source.USGS_Seamless.LayerSpecifications.NED.OneThirdArcSecond
            '                Case "Catchment Grid" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.CatchmentGrid
            '                Case "Catchment Polygons" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.CatchmentPolygons
            '                Case "Elevation Grid" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.ElevationGrid
            '                Case "Flow Accumulation Grid" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.FlowAccumulationGrid
            '                Case "Flow Direction Grid" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.FlowDirectionGrid
            '                Case "Slope Grid" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.SlopeGrid
            '                Case "Hydrography Area" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.Hydrography.Area
            '                Case "Hydrography Flowline" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.Hydrography.Flowline
            '                Case "Hydrography Line" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.Hydrography.Line
            '                Case "Hydrography Point" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.Hydrography.Point
            '                Case "Hydrography Waterbody" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.Hydrography.Waterbody
            '                Case "Hydrologic Units-Region Polygons" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.HydrologicUnits.RegionPolygons
            '                Case "Hydrologic Units-Sub Basin Polygons" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.HydrologicUnits.SubBasinPolygons
            '                Case "Hydrologic Units-Sub Watershed Polygons" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.HydrologicUnits.SubWatershedPolygons
            '                Case "Hydrologic Units-Watershed Polygons" : DataType = D4EM.Data.Source.NHDPlus.LayerSpecifications.HydrologicUnits.WatershedPolygons
            '                Case Else
            '                    Throw New IndexOutOfRangeException("Invalid DataType encountered.")
            '            End Select

            '            Dim SaveFolder As String = DataType.Tag & "_" & HUC
            '            Dim DownloadResults As String = ""
            '            Dim DownloadType As Integer = cboCategory.SelectedIndex
            '            Try
            '                'Debug.Print("start at " & Now)

            '                'With New Threading.Thread(New Threading.ThreadStart(
            '                '    Sub()
            '                '        Select Case DownloadType
            '                '            Case 0 : DownloadResults = D4EM.Data.Source.BASINS.GetBASINS(Project, SaveFolder, HUC, DataType)
            '                '            Case 1 : DownloadResults = D4EM.Data.Source.USGS_Seamless.Execute(Project, SaveFolder, DataType)
            '                '            Case 2 : DownloadResults = D4EM.Data.Source.NHDPlus.GetNHDPlus(Project, SaveFolder, HUC, True, New D4EM.Data.LayerSpecification() {DataType})
            '                '        End Select
            '                '    End Sub))

            '                '    While .ThreadState = Threading.ThreadState.Running
            '                '        If IsCancelled Then
            '                '            .Abort()
            '                '        End If
            '                '        Threading.Thread.Sleep(200)
            '                '        Debug.Print("Waiting...")
            '                '        Application.DoEvents()
            '                '    End While
            '                '    Debug.Print("finished at " & Now)
            '                'End With
            '                Select Case cboCategory.SelectedIndex
            '                    Case 0
            '                        DownloadResults = D4EM.Data.Source.BASINS.GetBASINS(Project, SaveFolder, HUC, DataType)
            '                    Case 1
            '                        DownloadResults = D4EM.Data.Source.USGS_Seamless.Execute(Project, SaveFolder, DataType)
            '                    Case 2
            '                        DownloadResults = D4EM.Data.Source.NHDPlus.GetNHDPlus(Project, SaveFolder, HUC, True, New D4EM.Data.LayerSpecification() {DataType})
            '                End Select
            '            Catch ex As Exception
            '                WarningMsg("Unable to download and/or extract information for: " & lstDataTypes.Items(i).ToString & "; The projection string on the downloaded layer may be invalid; you can try to manually open the file and correct this condition.\n\nThe detailed error was:\n\n{0}", ex.ToString)
            '                Continue For
            '            End Try

            '            'GetBasins contains XML with layers acquired, but will just load layers by looking for shape files

            '            'use XML file from BASINS to assign layer name, group, and initial visibility

            '            Dim DataDir As String = IO.Path.Combine(GISForm.LayerDirectory, SaveFolder)
            '            Dim arLayerFiles() As String = Nothing
            '            If My.Computer.FileSystem.DirectoryExists(DataDir) Then
            '                arLayerFiles = My.Computer.FileSystem.GetFiles(DataDir, FileIO.SearchOption.SearchAllSubDirectories, New String() {"*.shp", "*.tif"}).ToArray
            '                If arLayerFiles.Count = 0 Then
            '                    WarningMsg("No layer files were downloaded.")
            '                End If
            '            Else
            '                WarningMsg("No downloaded data could be found.")
            '                Exit For
            '            End If

            '            For Each lyrFile As String In arLayerFiles
            '                Dim lyr As IMapLayer = GISForm.GISMap.Layers.Add(lyrFile)
            '                GISForm.ApplyRendering(lyr, lyrFile, lstDataTypes.Items(i).ToString)
            '            Next
            '        End If
            '    Next
            'End If

            Debug.Print("DownloadLayers elapsed download time: {0:0.00}", sw.Elapsed.TotalSeconds)

            GISForm.GISMap.Layers.ResumeEvents()
            GISForm.GISMap.ZoomToMaxExtent()
            GISForm.GISLegend.RefreshNodes()
            GISForm.mnuLayerCollapseAll.PerformClick()

        Catch ex As Exception

            ErrorMsg(, ex)

        Finally

            IsDownloading = False
            GISForm.ProgressComplete()
            btnClose.Text = "Close"

        End Try

    End Sub

    Private Sub mnuView_Click(sender As Object, e As EventArgs) Handles mnuSelect2.Click, mnuZoomWindow2.Click, mnuZoomIn2.Click, mnuZoomOut2.Click, mnuZoomPrevious2.Click, mnuZoomExtents2.Click, mnuPan2.Click,
                                                                        tbSelect.Click, tbZoomWindow.Click, tbZoomIn.Click, tbZoomOut.Click, tbZoomPrevious.Click, tbZoomExtents.Click, tbPan.Click
        Try
            mnuSelect2.Checked = False
            mnuZoomIn2.Checked = False
            mnuZoomOut2.Checked = False
            mnuZoomWindow2.Checked = False
            mnuPan2.Checked = False
            tbSelect.Checked = False
            tbZoomIn.Checked = False
            tbZoomOut.Checked = False
            tbZoomWindow.Checked = False
            tbPan.Checked = False

            With HucMap
                If sender Is tbSelect Or sender Is mnuSelect2 Then
                    .FunctionMode = DotSpatial.Controls.FunctionMode.Select
                    mnuSelect2.Checked = True
                    tbSelect.Checked = True
                ElseIf sender Is tbZoomWindow Or sender Is mnuZoomWindow2 Then
                    .FunctionMode = DotSpatial.Controls.FunctionMode.ZoomIn
                    mnuZoomWindow2.Checked = True
                    tbZoomWindow.Checked = True
                ElseIf sender Is tbZoomIn Or sender Is mnuZoomIn2 Then
                    .FunctionMode = DotSpatial.Controls.FunctionMode.ZoomIn
                    .ZoomIn()
                    mnuZoomIn2.Checked = True
                    tbZoomIn.Checked = True
                ElseIf sender Is tbZoomOut Or sender Is mnuZoomOut2 Then
                    .ZoomOut()
                    .FunctionMode = DotSpatial.Controls.FunctionMode.ZoomOut
                    mnuZoomOut2.Checked = True
                    tbZoomOut.Checked = True
                ElseIf sender Is tbZoomPrevious Or sender Is mnuZoomPrevious2 Then
                    .ZoomToPrevious()
                    mnuSelect2.Checked = True
                    tbPan.Checked = True
                ElseIf sender Is tbZoomExtents Or sender Is mnuZoomExtents2 Then
                    HucMap.ZoomToMaxExtent()
                    mnuPan2.Checked = True
                    tbPan.Checked = True
                ElseIf sender Is tbPan Or sender Is mnuPan2 Then
                    .FunctionMode = DotSpatial.Controls.FunctionMode.Pan
                    mnuPan2.Checked = True
                    tbPan.Checked = True
                End If
            End With

        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Private Sub HucMap_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles HucMap.MouseDoubleClick
        If tbSelect.Checked Then 'switch back to pan mode
            tbPan.PerformClick()
        Else 'otherwise switch back to select mode
            tbSelect.PerformClick()
        End If
    End Sub

    Private Sub HucMap_MouseMove(sender As Object, e As MouseEventArgs) Handles HucMap.MouseMove
        'show tooltip containing HUC, county, and state names (all polygon layers)
        Dim pnt As DotSpatial.Topology.Coordinate = HucMap.PixelToProj(New Drawing.Point(e.X, e.Y))
        Static lasttxt As String = ""
        Dim txt As String = ""
        For Each lyr As Layer In HucMap.GetAllLayers
            If TypeOf lyr Is FeatureLayer Then
                With CType(lyr, FeatureLayer).DataSet
                    If .FeatureType = DotSpatial.Topology.FeatureType.Polygon Then
                        For i As Integer = 0 To .Features.Count - 1
                            If (TypeOf .Features(i).BasicGeometry Is DotSpatial.Topology.Polygon AndAlso CType(.Features(i).BasicGeometry, DotSpatial.Topology.Polygon).Intersects(pnt(0), pnt(1))) OrElse
                                (TypeOf .Features(i).BasicGeometry Is DotSpatial.Topology.MultiPolygon AndAlso CType(.Features(i).BasicGeometry, DotSpatial.Topology.MultiPolygon).Intersects(pnt(0), pnt(1))) Then
                                For j As Integer = 0 To .DataTable.Columns.Count - 1
                                    Dim colName As String = .DataTable.Columns(j).ColumnName.ToUpper
                                    If colName = "CU" Or colName.Contains("NAME") Then
                                        txt &= .Features(i).DataRow.Item(j) & vbCr
                                    End If
                                Next
                                Exit For
                            End If
                        Next
                    End If
                End With
            End If
        Next
        If txt <> lasttxt Then ToolTip1.SetToolTip(HucMap, txt)
        lasttxt = txt
    End Sub

    Private Sub txtHUC_MouseLeave(sender As Object, e As EventArgs) Handles txtHUC.MouseLeave
        UpdateBtnDownload()
    End Sub

    Private Sub UpdateBtnDownload()
        btnDownload.Enabled = IsNumeric(txtHUC.Text) AndAlso txtHUC.Text.Length = Choose(cboHUC.SelectedIndex + 1, 8, 12) AndAlso lstDataTypes.CheckedItems.Count > 0
    End Sub
End Class
